using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;

namespace CSW.Framework.Common.Data
{
    /// <summary>
    /// SqlParameter List.
    /// </summary>
    public class SqlParameterList
    {
        private readonly List<SqlParameter> m_SqlParameters = new List<SqlParameter>();

        /// <summary>
        /// Adds a VarChar parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddVarChar(string parameterName, string value)
        {
            SqlParameter p; 
            if (string.IsNullOrEmpty(value))
            {
                p = new SqlParameter(parameterName, DBNull.Value);
            }
            else
            {
                p = new SqlParameter(parameterName, value);
            }
            p.SqlDbType = SqlDbType.VarChar;

            m_SqlParameters.Add(p);
        }

        /// <summary>
        /// Adds an NVarChar parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddNVarChar(string parameterName, string value)
        {
            SqlParameter p;
            if (string.IsNullOrEmpty(value))
            {
                p = new SqlParameter(parameterName, DBNull.Value);
            }
            else
            {
                p = new SqlParameter(parameterName, value);
            }
            p.SqlDbType = SqlDbType.NVarChar;

            m_SqlParameters.Add(p);
        }

        /// <summary>
        /// Adds a Text parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddText(string parameterName, string value)
        {
            AddVarChar(parameterName, value);
        }

        /// <summary>
        /// Adds a Char parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddChar(string parameterName, string value)
        {
            AddVarChar(parameterName, value);
        }

        /// <summary>
        /// Adds an NChar parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddNChar(string parameterName, string value)
        {
            AddVarChar(parameterName, value);
        }

        /// <summary>
        /// Adds an Int parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddInt(string parameterName, int? value)
        {
            if (value == null)
                m_SqlParameters.Add(new SqlParameter(parameterName, DBNull.Value));
            else
                m_SqlParameters.Add(new SqlParameter(parameterName, value.Value));
        }

        /// <summary>
        /// Adds a TinyInt parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddTinyInt(string parameterName, int? value)
        {
            AddInt(parameterName, value);
        }

        /// <summary>
        /// Adds a SmallInt parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddSmallInt(string parameterName, int? value)
        {
            AddInt(parameterName, value);
        }

        /// <summary>
        /// Adds a Date parameter (without Time).
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddDateNoTime(string parameterName, DateTime? value)
        {
            if (value == null)
                m_SqlParameters.Add(new SqlParameter(parameterName, DBNull.Value));
            else
                m_SqlParameters.Add(new SqlParameter(parameterName, value.Value.Date));
        }

        /// <summary>
        /// Adds a DateTime parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddDateTime(string parameterName, DateTime? value)
        {
            if (value == null)
                m_SqlParameters.Add(new SqlParameter(parameterName, DBNull.Value));
            else
                m_SqlParameters.Add(new SqlParameter(parameterName, value.Value));
        }

        /// <summary>
        /// Adds a TimeStamp parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddTimeStamp(string parameterName, DateTime? value)
        {
            AddDateTime(parameterName, value);
        }

        /// <summary>
        /// Adds a Bit parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddBit(string parameterName, bool? value)
        {
            if (value == null)
                m_SqlParameters.Add(new SqlParameter(parameterName, DBNull.Value));
            else
                m_SqlParameters.Add(new SqlParameter(parameterName, value.Value));
        }

        /// <summary>
        /// Adds a Money parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddMoney(string parameterName, double? value)
        {
            SqlParameter p = new SqlParameter();
            p.ParameterName = parameterName;
            if (value == null) p.Value = DBNull.Value;
            else p.Value = value.Value;
            p.SqlDbType = SqlDbType.Money;
            m_SqlParameters.Add(p);        	
        }

        /// <summary>
        /// Adds a Real parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddReal(string parameterName, double? value)
        {
            SqlParameter p = new SqlParameter();
            p.ParameterName = parameterName;
            if (value == null) p.Value = DBNull.Value;
            else p.Value = value.Value;
            m_SqlParameters.Add(p);        	
        }

        /// <summary>
        /// Adds a Decimal parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <param name="value">The value.</param>
        public void AddDecimal(string parameterName, double? value)
        {
            AddReal(parameterName, value);
        }

        /// <summary>
        /// Gets the list as a SqlParameter array.
        /// </summary>
        /// <returns>The list as a SqlParameter array.</returns>
        public SqlParameter[] ToArray()
        {
            SqlParameter[] p = new SqlParameter[m_SqlParameters.Count];
            for (int i = 0; i < m_SqlParameters.Count; i++)
            {
                SqlParameter pItem = new SqlParameter {
                    ParameterName = m_SqlParameters[i].ParameterName, 
                    Value = m_SqlParameters[i].Value,
                    SqlDbType = m_SqlParameters[i].SqlDbType
                };

                p[i] = pItem;
            }
            return p;
        }

        /// <summary>
        /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            foreach (SqlParameter p in m_SqlParameters)
            {
                if (sb.Length != 0)
                    sb.Append(", ");

                sb.Append(string.Format("{0} = {1}", p.ParameterName, p.Value == DBNull.Value ? "NULL" : p.Value));
            }

            return sb.ToString();
        }
    }
}
